Xceed DataGrid for Silverlight Documentation
RatingCellEditor Class

Imports System.Windows
Imports System.Windows.Controls
Imports Xceed.Silverlight.DataGrid
Imports System
Imports System.Windows.Input
Imports System.Windows.Media.Imaging
 
 
 
Namespace Xceed.Silverlight.Documentation

  <TemplatePart( Name = "ImagesPanel", Type = GetType( Panel ) )>_
  Public Class RatingCellEditor 
                      Inherits Control
  
    Public Sub New()
      MyBase.New()    
      Me.DefaultStyleKey = GetType( RatingCellEditor )
    End Sub
 
 
 
 Public Shared ReadOnly ContentProperty As DependencyProperty = DependencyProperty.Register("Content", GetType(Object), 
              GetType(RatingCellEditor), 
                                                               New PropertyMetadata(Nothing, New PropertyChangedCallback(RatingCellEditor.OnContentChanged)))
 
Public Property Content() As Object
 Get
  Return Me.GetValue(RatingCellEditor.ContentProperty)
 End Get
 Set
  Me.SetValue(RatingCellEditor.ContentProperty, value)
 End Set
End Property
 
 
 
Private Shared Sub OnContentChanged(sender As DependencyObject, e As DependencyPropertyChangedEventArgs)
 Dim source As RatingCellEditor = TryCast(sender, RatingCellEditor)
 If source Is Nothing Then
  Return
 End If
 
 source.UpdateImages()
End Sub
 
 
 
    Public Overrides Sub OnApplyTemplate()
      MyBase.OnApplyTemplate()
 
      If Not m_imagesPanel Is Nothing Then
        Dim image As Image
        For Each image In m_imagesPanel.Children 
          RemoveHandler image.MouseLeftButtonDown, AddressOf OnImageMouseLeftButtonDown
        Next image
 
 
 
        m_imagesPanel.Children.Clear()
      End If
 
 
 
      m_imagesPanel = CType( Me.GetTemplateChild( "ImagesPanel" ), Panel )
 
 
 
      Me.UpdateImages()
    End Sub
 
 
 
    Protected Overrides Function MeasureOverride( ByVal availableSize As Size) As Size 
      Me.UpdateImages()
      Return MyBase.MeasureOverride( availableSize )
    End Function
 
 
 
    Private Sub UpdateImages()    
      If m_imagesPanel Is Nothing Then
        Return
      End If 
 
 
 
      Dim value As Integer = 0
 
 
 
      Try
        value = Convert.ToInt32( Me.Content )
      Catch( exception As InvalidCastException )
        'suppress
      End Try
 
 
 
      If value <> m_previousValue Then
        'Clear the previous images and unregister from MouseDown.
        Dim image as Image
        For Each image in m_imagesPanel.Children 
          RemoveHandler image.MouseLeftButtonDown, AddressOf OnImageMouseLeftButtonDown
        Next image
 
 
 
        m_imagesPanel.Children.Clear()
 
 
 
       Dim i As Integer 
       For i = 0 To i < 5
          Dim image As New Image()
          If i < value Then
            image.Source = RatingCellEditor.FullImage
          Else
            image.Source = RatingCellEditor.EmptyImage
          End If
 
 
 
          AddHandler image.MouseLeftButtonDown, AddressOf New MouseButtonEventHandler( Me.OnImageMouseLeftButtonDown )
          m_imagesPanel.Children.Add( image )
        Next i
 
 
 
        m_previousValue = value
      End If
    End Sub
 
 
 
    Private Sub OnImageMouseLeftButtonDown( ByVal sender As Object, ByVal e As MouseButtonEventArgs )
      ME.Content = m_imagesPanel.Children.IndexOf( CType( sender, Image ) ) + 1
    End Sub
 
 
 
    Private m_imagesPanel As Panel 
    Private m_previousValue As Integer = int.MinValue
 
 
 
    Private Static FullImage As New BitmapImage( New Uri( "Images/star.png", UriKind.Relative ) )
    Private Static EmptyImage As New BitmapImage( New Uri( "Images/emptystar.png", UriKind.Relative ) )
 
  End Class
End Namespace
using System.Windows;
using System.Windows.Controls;
using Xceed.Silverlight.DataGrid;
using System;
using System.Windows.Input;
using System.Windows.Media.Imaging;
 
 
 
namespace Xceed.Silverlight.Documentation
{
  [TemplatePart( Name = "ImagesPanel", Type = typeof( Panel ) )]
  public class RatingCellEditor : Control
  {
    public RatingCellEditor()
      : base()
    {
      this.DefaultStyleKey = typeof( RatingCellEditor );
    }
 
 
 
 public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
  "Content",
  typeof( object ),
  typeof( RatingCellEditor ),
  new PropertyMetadata( null, new PropertyChangedCallback( RatingCellEditor.OnContentChanged ) ) );
 
 
 
public object Content
{
  get
  {
    return this.GetValue( RatingCellEditor.ContentProperty );
  }
  set
  {
    this.SetValue( RatingCellEditor.ContentProperty, value );
  }
}
 
 
 
private static void OnContentChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e )
{
  RatingCellEditor source = sender as RatingCellEditor;
  if( source == null )
    return;
 
  source.UpdateImages();
}

 
    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();
 
      if( m_imagesPanel != null )
      {
        foreach( Image image in m_imagesPanel.Children )
        {
          image.MouseLeftButtonDown -= OnImageMouseLeftButtonDown;
        }
 
 
 
        m_imagesPanel.Children.Clear();
      }
 
 
 
      m_imagesPanel = this.GetTemplateChild( "ImagesPanel" ) as Panel;
 
 
 
      this.UpdateImages();
    }
 
 
 
    protected override Size MeasureOverride( Size availableSize )
    {
      this.UpdateImages();
      return base.MeasureOverride( availableSize );
    }
 
 
 
    private void UpdateImages()
    {
      if( m_imagesPanel == null )
        return;
 
 
 
      int value = 0;
 
 
 
      try
      {
        value = Convert.ToInt32( this.Content );
      }
      catch( InvalidCastException )
      {
        //suppress
      }
 
 
 
      if( value != m_previousValue )
      {
        //Clear the previous images and unregister from MouseDown.
        foreach( Image image in m_imagesPanel.Children )
        {
          image.MouseLeftButtonDown -= OnImageMouseLeftButtonDown;
        }
 
 
 
        m_imagesPanel.Children.Clear();
 
 
 
        for( int i = 0; i < 5; i++ )
        {
          Image image = new Image();
          if( i < value )
          {
            image.Source = RatingCellEditor.FullImage;
          }
          else
          {
            image.Source = RatingCellEditor.EmptyImage;
          }
 
 
 
          image.MouseLeftButtonDown += new MouseButtonEventHandler( this.OnImageMouseLeftButtonDown );
          m_imagesPanel.Children.Add( image );
        }
 
 
 
        m_previousValue = value;
      }
    }
 
 
 
    private void OnImageMouseLeftButtonDown( object sender, MouseButtonEventArgs e )
    {
      this.Content = m_imagesPanel.Children.IndexOf( sender as Image ) + 1;
    }
 
 
 
    private Panel m_imagesPanel;
    private int m_previousValue = int.MinValue;
 
 
 
    private static BitmapImage FullImage = new BitmapImage( new Uri( "Images/star.png", UriKind.Relative ) );
    private static BitmapImage EmptyImage = new BitmapImage( new Uri( "Images/emptystar.png", UriKind.Relative ) );
 
  }
}

Using the RatingCellEditor

The following code demonstrates how to use the RatingCellEditor to edit the content of a cell. 

<Style TargetType="local:RatingCellEditor">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:RatingCellEditor">
<StackPanel x:Name="ImagesPanel"
Orientation="Horizontal" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

It is also important to set the editor's DefaultStyleKey property to its own type in its constructor in order to be able to provide it with a default style.

Public Sub New()
MyBase.New()
Me.DefaultStyleKey = GetType( RatingCellEditor )
End Sub
public RatingCellEditor()
: base()
{
this.DefaultStyleKey = typeof( RatingCellEditor );
}

Although not required to edit using the RatingCellEditor, the CellContentTemplate is also defined in the example below to demonstrate how to create the "visualization" counterpart of the editor.
<sldg:Column FieldName="Rating">
<sldg:Column.CellEditorTemplate>
<DataTemplate>
<ContentControl x:Name="ratingControl">
<ContentControl.ContentTemplate>
<DataTemplate>
<local:RatingCellEditor Content="{Binding Path=Content, ElementName=ratingControl, Mode=TwoWay}" />
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</DataTemplate>
</sldg:Column.CellEditorTemplate>
</sldg:Column>

 

Send Feedback